<template>
  <div class="map-container" ref="mapContainer">
    <div class="search-box" v-if="editable">
      <el-input
        v-model="searchKeyword"
        placeholder="搜索地点"
        @keyup.enter.native="handleSearch"
      >
        <el-button slot="append" icon="el-icon-search" @click="handleSearch"></el-button>
      </el-input>
    </div>
  </div>
</template>

<script>
export default {
  name: 'AMapGL',
  props: {
    // 经度
    longitude: {
      type: [Number, String],
      default: 116.404
    },
    // 纬度
    latitude: {
      type: [Number, String],
      default: 39.915
    },
    // 缩放级别
    zoom: {
      type: Number,
      default: 18
    },
    // 是否允许编辑（拖动标记点）
    editable: {
      type: Boolean,
      default: false
    },
    // 3D视角参数
    viewOptions: {
      type: Object,
      default: () => ({
        pitch: 60,      // 倾斜角度
        rotation: 45,   // 旋转角度
        showControls: true // 是否显示3D控件
      })
    }
  },
  data() {
    return {
      map: null,
      marker: null,
      markers: [],
      searchKeyword: '',
      placeSearch: null,
      geocoder: null,
      infoWindows: new Map(), // 使用Map存储信息窗体实例，key为markerId
      infoWindowCount: 0, // 用于生成唯一ID
      baseZIndex: 999, // 基础z-index值
      currentMaxZIndex: 999 // 当前最大z-index值
    }
  },
  mounted() {
    this.initMap()
    // 添加全局关闭函数
    window._closeInfoWindow = (id) => {
      const infoEl = document.getElementById(id)
      if (infoEl) {
        infoEl.remove()
        const markerId = id.split('_')[1] // 使用markerId作为key
        this.infoWindows.delete(markerId)
      }
    }
  },
  methods: {
    initMap() {
      // 确保高德地图脚本已加载
      if (typeof AMap === 'undefined') {
        // 设置安全密钥
        window._AMapSecurityConfig = {
          securityJsCode: process.env.VUE_APP_AMAP_SECURITY_CODE
        }
        
        const script = document.createElement('script')
        script.src = `https://webapi.amap.com/maps?v=2.0&key=${process.env.VUE_APP_AMAP_KEY}&plugin=AMap.Scale,AMap.ToolBar,AMap.PlaceSearch,AMap.Geocoder,AMap.AutoComplete,Map3D&callback=initAMapGL`
        document.body.appendChild(script)
        window.initAMapGL = () => {
          this.initMapInstance()
        }
      } else {
        this.initMapInstance()
      }
    },
    initMapInstance() {
      // 创建地图实例
      this.map = new AMap.Map(this.$refs.mapContainer, {
        zoom: this.zoom,
        center: [this.longitude, this.latitude],
        viewMode: '3D',
        pitch: this.viewOptions.pitch,
        rotation: this.viewOptions.rotation,
        mapStyle: 'amap://styles/blue',
        features: ['bg', 'building', 'point', 'road'],
        buildingAnimation: true,
        skyColor: '#091220',
        showBuildingBlock: true, // 显示建筑物块面
        showIndoorMap: false,  // 关闭室内地图
        buildingStyle: {
          buildingColor: '#66A9FF', // 更亮的蓝色
          strokeColor: '#A6D1FF', // 更亮的边框颜色
          strokeOpacity: 1, // 建筑物边框透明度
          fillColor: '#66A9FF', // 建筑物填充颜色
          fillOpacity: 0.9, // 建筑物填充透明度
          heightScale: 1, // 建筑物高度比例
          buildingAnimation: true, // 建筑物出现动画
          sortByHeight: true // 按高度排序
        }
      })

      // 加载3D建筑物图层
      const buildings = new AMap.Buildings({
        zooms: [16, 20],
        zIndex: 10,
        heightFactor: 1,
        // styles: {
        //   buildingStyle: {
        //     color: '#66A9FF', // 建筑物颜色
        //     stroke: '#A6D1FF', // 建筑物边框颜色
        //     strokeOpacity: 1,
        //     fillOpacity: 0.9,
        //   }
        // }
      });
      this.map.add(buildings);

      // 添加地图控件
      if (this.viewOptions.showControls) {
        this.map.addControl(new AMap.Scale())
        this.map.addControl(new AMap.ToolBar({
          position: 'RB'
        }))
      }

      // 添加标记点
      this.marker = new AMap.Marker({
        position: [this.longitude, this.latitude],
        draggable: this.editable,
        icon: new AMap.Icon({
          size: new AMap.Size(25, 34),
          image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
          imageSize: new AMap.Size(25, 34)
        })
      })
      this.map.add(this.marker)

      if (this.editable) {
        // 初始化搜索服务
        AMap.plugin(['AMap.PlaceSearch', 'AMap.Geocoder'], () => {
          this.placeSearch = new AMap.PlaceSearch({
            city: '全国',
            pageSize: 1,
            pageIndex: 1,
            extensions: 'all'
          })

          this.geocoder = new AMap.Geocoder()
        })

        // 标记点拖动结束事件
        this.marker.on('dragend', () => {
          const position = this.marker.getPosition()
          this.$emit('marker-move', {
            longitude: position.getLng(),
            latitude: position.getLat()
          })
        })

        // 点击地图更新标记点位置
        this.map.on('click', (e) => {
          const position = e.lnglat
          this.marker.setPosition([position.getLng(), position.getLat()])
          this.$emit('marker-move', {
            longitude: position.getLng(),
            latitude: position.getLat()
          })
        })
      }

      // 触发地图加载完成事件
      this.$emit('map-ready', this.map)
    },
    handleSearch() {
      if (this.searchKeyword && this.placeSearch) {
        this.placeSearch.search(this.searchKeyword, (status, result) => {
          if (status === 'complete') {
            if (result.poiList && result.poiList.pois && result.poiList.pois.length > 0) {
              const firstPoi = result.poiList.pois[0]
              const position = [firstPoi.location.lng, firstPoi.location.lat]
              this.marker.setPosition(position)
              this.map.setCenter(position)
              this.$emit('marker-move', {
                longitude: firstPoi.location.lng,
                latitude: firstPoi.location.lat
              })
              this.$message.success('已定位到: ' + firstPoi.name)
            } else {
              this.$message.warning('未找到相关地点')
            }
          } else {
            this.$message.error('搜索失败，请重试')
          }
        })
      } else {
        this.$message.warning('请输入搜索关键词')
      }
    },
    clearAllOverlays() {
      if (this.map) {
        this.map.clearMap()
        // 清除所有信息窗体
        this.infoWindows.forEach((info, id) => {
          const infoEl = document.getElementById(`info_${id}`)
          if (infoEl) {
            // 移除事件监听器
            if (infoEl._handleClick) {
              infoEl.removeEventListener('mousedown', infoEl._handleClick)
            }
            infoEl.remove()
          }
        })
        this.infoWindows.clear()
        // 重置最大z-index值
        this.currentMaxZIndex = this.baseZIndex
      }
    },
    // 创建自定义信息窗体
    createCustomInfoWindow(content, position) {
      const container = document.createElement('div')
      container.style.cssText = `
        position: absolute;
        z-index: ${this.currentMaxZIndex};
        transform: translate(-50%, -100%);
        pointer-events: auto;
        cursor: move;
      `
      container.innerHTML = content
      
      // 更新位置
      const pixel = this.map.lngLatToContainer(position)
      container.style.left = pixel.x + 'px'
      container.style.top = (pixel.y - 20) + 'px' // 20px offset

      // 添加点击事件，将窗体置于顶层
      const handleClick = (e) => {
        // 阻止事件冒泡
        e.stopPropagation()
        // 将当前窗体置于顶层
        this.bringToFront(container)
      }

      // 为整个容器添加点击事件
      container.addEventListener('mousedown', handleClick)

      // 存储事件处理函数，以便后续移除
      container._handleClick = handleClick

      return container
    },

    // 将窗体置于顶层
    bringToFront(element) {
      this.currentMaxZIndex++
      // 将当前窗体的z-index设置为最新的最大值
      element.style.zIndex = this.currentMaxZIndex
      // 添加激活状态的样式
      element.style.boxShadow = '0 4px 16px rgba(0, 0, 0, 0.3)'
      // 移除其他窗体的激活状态
      const infoWindows = document.querySelectorAll('[id^="info_"]')
      infoWindows.forEach(window => {
        if (window !== element) {
          window.style.boxShadow = '0 2px 12px rgba(0, 0, 0, 0.5)'
        }
      })
    },

    // 创建信息窗体内容
    createInfoContent(infoWindowId, markerId) {
      // 根据类型设置不同的颜色主题
      const theme = this.markers.find(m => m.getExtData().markerId === markerId).type === 'house' 
        ? {
            bg: 'rgba(67, 15, 42, 0.95)', // 深粉色背景
            border: '#ff4d7a', // 亮粉色边框
            title: '#ff85a0', // 浅粉色标题
            label: '#ff85a0', // 浅粉色标签
            borderOpacity: '0.3'
          }
        : {
            bg: 'rgba(67, 42, 15, 0.95)', // 深橙色背景
            border: '#ff8c1a', // 亮橙色边框
            title: '#ffa64d', // 浅橙色标题
            label: '#ffa64d', // 浅橙色标签
            borderOpacity: '0.3'
          };

      return `
        <div id="${infoWindowId}" data-marker-id="${markerId}" class="info-window" style="
          position: relative;
          padding: 15px;
          border-radius: 8px;
          background: ${theme.bg};
          border: 1px solid ${theme.border};
          color: #fff;
          box-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
          min-width: 280px;
          transition: all 0.3s ease;
          user-select: none;
        ">
          <div class="info-close" style="
            position: absolute;
            top: 10px;
            right: 10px;
            width: 20px;
            height: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            color: ${theme.title};
            font-size: 18px;
            transition: all 0.3s;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.1);
          " onclick="window._closeInfoWindow('${infoWindowId}')">×</div>
          <div style="
            font-size: 16px;
            font-weight: bold;
            margin-bottom: 12px;
            color: ${theme.title};
            border-bottom: 1px solid ${theme.border}${theme.borderOpacity};
            padding-bottom: 8px;
            padding-right: 20px;
          ">${this.markers.find(m => m.getExtData().markerId === markerId).title || '未知'}</div>
          <div style="font-size: 14px;">
            <div style="
              margin: 8px 0;
              display: flex;
              align-items: flex-start;
            ">
              <span style="
                color: ${theme.label};
                margin-right: 12px;
                white-space: nowrap;
              ">地址：</span>
              <span style="
                flex: 1;
                word-break: break-all;
                color: rgba(255, 255, 255, 0.85);
              ">${this.markers.find(m => m.getExtData().markerId === markerId).address || '未知'}</span>
            </div>
            <div style="
              margin: 8px 0;
              display: flex;
              align-items: flex-start;
            ">
              <span style="
                color: ${theme.label};
                margin-right: 12px;
                white-space: nowrap;
              ">用途：</span>
              <span style="
                flex: 1;
                word-break: break-all;
                color: rgba(255, 255, 255, 0.85);
              ">${this.markers.find(m => m.getExtData().markerId === markerId).purpose || '未知'}</span>
            </div>
            ${this.markers.find(m => m.getExtData().markerId === markerId).type === 'house' ? `
              <div style="
                margin: 8px 0;
                display: flex;
                align-items: flex-start;
              ">
                <span style="
                  color: ${theme.label};
                  margin-right: 12px;
                  white-space: nowrap;
                ">建筑面积：</span>
                <span style="
                  flex: 1;
                  word-break: break-all;
                  color: rgba(255, 255, 255, 0.85);
                ">${this.markers.find(m => m.getExtData().markerId === markerId).area || '未知'} m²</span>
              </div>
            ` : ''}
          </div>
          <div style="
            position: absolute;
            left: 50%;
            bottom: -8px;
            transform: translateX(-50%) rotate(45deg);
            width: 16px;
            height: 16px;
            background: ${theme.bg};
            border-right: 1px solid ${theme.border};
            border-bottom: 1px solid ${theme.border};
            box-shadow: 4px 4px 8px -4px rgba(0, 0, 0, 0.5);
          "></div>
        </div>
      `
    },

    // 更新所有信息窗体的位置
    updateInfoWindowsPosition() {
      this.infoWindows.forEach((info) => {
        if (info.marker && info.element) {
          const pixel = this.map.lngLatToContainer(info.marker.getPosition())
          info.element.style.left = pixel.x + 'px'
          info.element.style.top = (pixel.y - 20) + 'px'
        }
      })
    },

    async addMarkersToMap(markersData) {
      try {
        // 清除现有的所有覆盖物
        this.clearAllOverlays()
        this.markers = []

        // 添加新的标记点
        if (Array.isArray(markersData) && markersData.length > 0) {
          markersData.forEach((markerData, index) => {
            const markerId = `marker_${index}`
            const marker = new AMap.Marker({
              position: [markerData.longitude, markerData.latitude],
              title: markerData.title,
              icon: new AMap.Icon({
                size: new AMap.Size(32, 34),
                image: markerData.icon || '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
                imageSize: new AMap.Size(32, 34)
              }),
              cursor: 'pointer',
              extData: { markerId } // 存储markerId
            })

            // 创建信息窗体内容
            const createInfoContent = (infoWindowId, markerId) => {
              // 根据类型设置不同的颜色主题
              const theme = markerData.type === 'house' 
                ? {
                    bg: 'rgba(67, 15, 42, 0.95)', // 深粉色背景
                    border: '#ff4d7a', // 亮粉色边框
                    title: '#ff85a0', // 浅粉色标题
                    label: '#ff85a0', // 浅粉色标签
                    borderOpacity: '0.3'
                  }
                : {
                    bg: 'rgba(67, 42, 15, 0.95)', // 深橙色背景
                    border: '#ff8c1a', // 亮橙色边框
                    title: '#ffa64d', // 浅橙色标题
                    label: '#ffa64d', // 浅橙色标签
                    borderOpacity: '0.3'
                  };

              return `
                <div id="${infoWindowId}" data-marker-id="${markerId}" style="
                  position: relative;
                  padding: 15px;
                  border-radius: 8px;
                  background: ${theme.bg};
                  border: 1px solid ${theme.border};
                  color: #fff;
                  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
                  min-width: 280px;
                  transition: all 0.3s ease;
                  user-select: none;
                "
                >
                  <div class="info-close" style="
                    position: absolute;
                    top: 10px;
                    right: 10px;
                    width: 20px;
                    height: 20px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    cursor: pointer;
                    color: ${theme.title};
                    font-size: 18px;
                    transition: all 0.3s;
                    border-radius: 50%;
                    background: rgba(255, 255, 255, 0.1);
                  " onclick="window._closeInfoWindow('${infoWindowId}')">×</div>
                  <div style="
                    font-size: 16px;
                    font-weight: bold;
                    margin-bottom: 12px;
                    color: ${theme.title};
                    border-bottom: 1px solid ${theme.border}${theme.borderOpacity};
                    padding-bottom: 8px;
                    padding-right: 20px;
                  ">${markerData.title || '未知'}</div>
                  <div style="font-size: 14px;">
                    <div style="
                      margin: 8px 0;
                      display: flex;
                      align-items: flex-start;
                    ">
                      <span style="
                        color: ${theme.label};
                        margin-right: 12px;
                        white-space: nowrap;
                      ">地址：</span>
                      <span style="
                        flex: 1;
                        word-break: break-all;
                        color: rgba(255, 255, 255, 0.85);
                      ">${markerData.address || '未知'}</span>
                    </div>
                    <div style="
                      margin: 8px 0;
                      display: flex;
                      align-items: flex-start;
                    ">
                      <span style="
                        color: ${theme.label};
                        margin-right: 12px;
                        white-space: nowrap;
                      ">用途：</span>
                      <span style="
                        flex: 1;
                        word-break: break-all;
                        color: rgba(255, 255, 255, 0.85);
                      ">${markerData.purpose || '未知'}</span>
                    </div>
                    ${markerData.type === 'house' ? `
                      <div style="
                        margin: 8px 0;
                        display: flex;
                        align-items: flex-start;
                      ">
                        <span style="
                          color: ${theme.label};
                          margin-right: 12px;
                          white-space: nowrap;
                        ">建筑面积：</span>
                        <span style="
                          flex: 1;
                          word-break: break-all;
                          color: rgba(255, 255, 255, 0.85);
                        ">${markerData.area || '未知'} m²</span>
                      </div>
                    ` : ''}
                  </div>
                  <div style="
                    position: absolute;
                    left: 50%;
                    bottom: -8px;
                    transform: translateX(-50%) rotate(45deg);
                    width: 16px;
                    height: 16px;
                    background: ${theme.bg};
                    border-right: 1px solid ${theme.border};
                    border-bottom: 1px solid ${theme.border};
                    box-shadow: 4px 4px 8px -4px rgba(0, 0, 0, 0.5);
                  "></div>
                </div>
              `
            }

            // 创建或显示信息窗体的函数
            const showInfoWindow = () => {
              const markerId = marker.getExtData().markerId
              const infoWindowId = `info_${markerId}`
              
              // 如果窗体已存在且仍在DOM中，不需要创建新的
              const existingWindow = document.getElementById(infoWindowId)
              if (existingWindow) {
                return
              }

              // 创建新的信息窗体
              const content = createInfoContent(infoWindowId, markerId)
              const infoWindow = this.createCustomInfoWindow(content, marker.getPosition())
              this.$refs.mapContainer.appendChild(infoWindow)
              
              // 存储信息窗体信息
              this.infoWindows.set(markerId, {
                element: infoWindow,
                marker: marker
              })
            }

            // 鼠标悬停事件
            marker.on('mouseover', showInfoWindow)

            // 点击事件
            if (markerData.onClick) {
              marker.on('click', () => {
                markerData.onClick(markerData)
              })
            }

            this.markers.push(marker)
            this.map.add(marker)
          })

          // 自动调整视野到包含所有标记点
          this.map.setFitView(this.markers)

          // 添加地图移动/缩放监听，更新信息窗体位置
          this.map.on('mapmove', this.updateInfoWindowsPosition)
          this.map.on('zoomchange', this.updateInfoWindowsPosition)
        }
      } catch (error) {
        console.error('添加标记点失败:', error)
        throw error
      }
    },
    
    // 组件销毁时清理
    beforeDestroy() {
      // 移除地图事件监听
      if (this.map) {
        this.map.off('mapmove', this.updateInfoWindowsPosition)
        this.map.off('zoomchange', this.updateInfoWindowsPosition)
      }
      // 清除所有信息窗体和事件监听器
      this.clearAllOverlays()
    }
  },
  watch: {
    longitude(newVal) {
      if (this.marker) {
        const position = this.marker.getPosition()
        this.marker.setPosition([newVal, position.getLat()])
        this.map.setCenter([newVal, position.getLat()])
      }
    },
    latitude(newVal) {
      if (this.marker) {
        const position = this.marker.getPosition()
        this.marker.setPosition([position.getLng(), newVal])
        this.map.setCenter([position.getLng(), newVal])
      }
    },
    'viewOptions.pitch'(newVal) {
      if (this.map) {
        this.map.setPitch(newVal)
      }
    },
    'viewOptions.rotation'(newVal) {
      if (this.map) {
        this.map.setRotation(newVal)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.map-container {
  width: 100%;
  height: 100%;
  position: relative;
}

// 添加信息窗体样式
:deep(.map-info-window) {
  padding: 15px;
  border-radius: 8px;
  background: #001529;  // 改为不透明的深色背景
  border: 1px solid #1890ff;
  color: #fff;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
  min-width: 280px;
  position: relative;

  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: linear-gradient(135deg, #1890ff 0%, #001529 100%);
    opacity: 0.1;
    border-radius: 8px;
    z-index: -1;
  }

  .info-title {
    font-size: 16px;
    font-weight: bold;
    margin-bottom: 12px;
    color: #1890ff;
    border-bottom: 1px solid #1890ff;
    padding-bottom: 8px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  }

  .info-content {
    font-size: 14px;

    .info-item {
      margin: 8px 0;
      display: flex;
      align-items: flex-start;

      .label {
        color: #1890ff;
        margin-right: 12px;
        white-space: nowrap;
      }

      .value {
        flex: 1;
        word-break: break-all;
        color: #fff;
      }
    }
  }
}

// 修改高德地图信息窗体的默认样式
:deep(.amap-info-content) {
  padding: 0;
  background: transparent;
  border: none;
  box-shadow: none;
}

:deep(.amap-info-close) {
  display: none;
}

:deep(.amap-info-sharp) {
  display: none;
}

:deep(.amap-info-outer),
:deep(.amap-info-inner) {
  background: transparent;
  border: none;
  box-shadow: none;
}

.search-box {
  position: absolute;
  top: 20px;
  left: 20px;
  width: 300px;
  z-index: 9999;
  background-color: #fff;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  pointer-events: auto;
}

.search-box :deep(.el-input__inner) {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

.search-box :deep(.el-input-group__append) {
  background-color: var(--el-color-primary);
  border-color: var(--el-color-primary);
  color: white;
  padding: 0 15px;
}
</style> 